package com.example.comsys.service.impl;

import com.example.comsys.dao.EmployeeDAO;
import com.example.comsys.dataobject.EmployeeDO;
import com.example.comsys.model.Department;
import com.example.comsys.model.Employee;
import com.example.comsys.model.Page;
import com.example.comsys.param.EmployeeQueryParam;
import com.example.comsys.param.PageQueryParam;
import com.example.comsys.service.DepartmentService;
import com.example.comsys.service.EmployeeService;
import com.example.comsys.util.ConvertUtils;
import com.example.comsys.util.ConvertUtils.EmployeeUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * Employee service impl
 *
 * @author wjh
 * @date 2019/12/30, 周一
 */
@Service
public class EmployeeServiceImpl implements EmployeeService{

  @Autowired
  private EmployeeDAO employeeDAO;

  @Autowired
  private DepartmentService departmentService;

  @Override
  public Employee addEmployee(Employee employee) {

    EmployeeDO employeeDO = EmployeeUtils.employeeToDO(employee);
    int insert = employeeDAO.insert(employeeDO);
    if (insert != 1) {
      return null;
    }
    employee.setEmployeeId(employeeDO.getEmployeeId());
    return employee;
  }

  @Override
  public Employee queryEmployeeByEmployeeId(long employeeId) {

    if (employeeId <= 0) {
      return null;
    }
    EmployeeDO employeeDO = employeeDAO.selectByPrimaryKey(employeeId);

    if (employeeDO != null) {
      return ConvertUtils.EmployeeUtils.employeeToModel(employeeDO);
    }
    return null;
  }

  // @Override
  // public Page<List<Employee>> queryEmployeeByParam(EmployeeQueryParam param) {
  //
  //   List<EmployeeDO> employeeDos = employeeDAO.selectByParam(param);
  //   if (employeeDos != null && employeeDos.size() > 0) {
  //
  //     Map<Long, Department> departMap = new HashMap<>(employeeDos.size() << 1);
  //
  //     List<Employee> employeeList = employeeDos.stream()
  //         .map(EmployeeUtils::employeeToModel)
  //         .filter(Objects::nonNull)
  //         .peek(v -> departMap.put(v.getDepartment().getDepartId(), null))
  //         .collect(Collectors.toList());
  //
  //     if (param == null || !param.isDetailDepart()) {
  //       departMap.clear();
  //       return employeeList;
  //     }
  //     // query detail department info
  //     List<Department> departments = departmentService.batchQueryDepartments(departMap.keySet().toArray(new Long[]{}));
  //     // set department map
  //     departments.forEach(department -> departMap.putIfAbsent(department.getDepartId(), department));
  //     // set employee department
  //     employeeList.forEach(employee -> employee.setDepartment(departMap.get(employee.getDepartment().getDepartId())));
  //     return employeeList;
  //   }
  //   return new ArrayList<>();
  // }

  @Override
  public List<Employee> queryEmployeeByDepartment(long departmentId) {
    if (departmentId <= 0) {
      return null;
    }
    EmployeeQueryParam queryParam = new EmployeeQueryParam();
    queryParam.setDepartmentId(departmentId);
    queryParam.setLimit(false);
    return queryDataByParam(queryParam).getData();
  }

  @Override
  public Employee updateEmployeeByEmployeeId(Employee employee) {
    if (employee == null || employee.getEmployeeId() <= 0) {
      return null;
    }
    Employee orgEmployee = queryEmployeeByEmployeeId(employee.getEmployeeId());
    BeanUtils.copyProperties(employee, orgEmployee, "employeeId", "gmtCreated", "gmtModified");
    EmployeeDO updatedDO = EmployeeUtils.employeeToDO(orgEmployee);
    if (updatedDO != null) {
      int update = employeeDAO.updateByPrimaryKey(updatedDO);
      return (update == 1) ? orgEmployee : null;
    }
    return null;
  }

  @Override
  public boolean deleteEmployee(long employeeId) {
    if (employeeId <= 0) {
      return false;
    }
    int delete = employeeDAO.deleteByPrimaryKey(employeeId);
    return (delete == 1);
  }

  @Override
  public HSSFWorkbook generateExcel(String filename, Object... args) {

    EmployeeQueryParam queryParam = new EmployeeQueryParam();
    queryParam.setLimit(false);
    queryParam.setDetailDepart(true);
    Page<Employee> employeePage = queryDataByParam(queryParam);
    List<Employee> data = employeePage.getData();
    if (data == null || data.size() == 0) {
      return null;
    }

    HSSFWorkbook wb = new HSSFWorkbook();
    //建立新的sheet对象（excel的表单）
    HSSFSheet sheet = wb.createSheet(filename);
    sheet.setVerticallyCenter(true);
    HSSFCellStyle styleMain = wb.createCellStyle();
    //水平居中
    styleMain.setAlignment(HorizontalAlignment.CENTER);
    //垂直居中
    styleMain.setVerticalAlignment(VerticalAlignment.CENTER);

    //在sheet里创建第一行，参数为行索引(excel的行)，可以是0～65535之间的任何一个
    HSSFRow row1 = sheet.createRow(0);
    //创建单元格（excel的单元格，参数为列索引，可以是0～255之间的任何一个
    HSSFCell cell = row1.createCell(0);
    row1.setHeight((short) 500);

    //设置单元格内容
    cell.setCellValue("员工信息统计一览表");
    //合并单元格CellRangeAddress构造参数依次表示起始行，截至行，起始列， 截至列
    sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 13));
    //在sheet里创建第二行

    HSSFRow row2 = sheet.createRow(1);
    //创建单元格并设置单元格内容
    row2.createCell(0).setCellValue("员工编号");
    row2.createCell(1).setCellValue("姓名");
    row2.createCell(2).setCellValue("性别");
    row2.createCell(3).setCellValue("年龄");
    row2.createCell(4).setCellValue("部门");
    row2.createCell(5).setCellValue("基本薪资");
    row2.createCell(6).setCellValue("基本奖金");
    row2.createCell(7).setCellValue("手机");
    row2.createCell(8).setCellValue("邮箱");
    row2.createCell(9).setCellValue("地址");
    row2.createCell(10).setCellValue("工作状态");
    row2.createCell(11).setCellValue("入职时间");
    row2.createCell(12).setCellValue("上次职位变动时间");
    row2.setRowStyle(styleMain);
    //在sheet里创建第三行

    for (int i = 0; i < data.size(); i++) {

      if (i <= 10) {
        sheet.setColumnWidth(i, 2588);
      } else {
        sheet.setColumnWidth(i, 6000);
      }

      Employee employee = data.get(i);
      HSSFRow row = sheet.createRow(i + 2);
      row.setRowStyle(styleMain);

      row.createCell(0).setCellValue(employee.getEmployeeId());
      row.createCell(1).setCellValue(employee.getName());
      row.createCell(2).setCellValue(employee.getSex());
      row.createCell(3).setCellValue(employee.getAge());
      row.createCell(4).setCellValue(employee.getDepartment().getName());
      row.createCell(5).setCellValue(employee.getBaseSalary());
      row.createCell(6).setCellValue(employee.getBaseBonus());
      row.createCell(7).setCellValue(employee.getPhone());
      row.createCell(8).setCellValue(employee.getEmail());
      row.createCell(9).setCellValue(employee.getAddress());
      row.createCell(10).setCellValue(employee.getState().toString());
      row.createCell(11).setCellValue(employee.getGmtCreated().toString());
      row.createCell(12).setCellValue(employee.getGmtModified().toString());

    }
    return wb;

  }


  @Override
  public Page<Employee> queryDataByParam(EmployeeQueryParam queryParam) {

    if (queryParam == null) {
      queryParam = new EmployeeQueryParam();
    }
    if (queryParam.getPageQueryParam() == null) {
      queryParam.setPageQueryParam(new PageQueryParam());
    }

    // 查询当前也数据
    List<EmployeeDO> employeeDos = employeeDAO.selectByParam(queryParam);
    // 查询总记录数
    Integer count = employeeDAO.selectCount();
    // 返回分页数据模型
    Page<Employee> data = new Page<>();

    data.setCurrentPage(queryParam.getPageQueryParam().getCurrentPage());
    data.setPageSize(queryParam.getPageQueryParam().getPageSize());

    if (employeeDos != null && employeeDos.size() > 0) {

      Map<Long, Department> departMap = new HashMap<>(employeeDos.size() << 1);

      List<Employee> employeeList = employeeDos.stream()
          .map(EmployeeUtils::employeeToModel)
          .filter(Objects::nonNull)
          .peek(v -> departMap.put(v.getDepartment().getDepartId(), null))
          .collect(Collectors.toList());

      data.setTotalItems(employeeList.size());
      data.setTotalPages(count / queryParam.getPageQueryParam().getPageSize() + 1);
      data.setData(employeeList);
      data.setTotalSize(count);

      if (!queryParam.isDetailDepart()) {
        departMap.clear();
        return data;
      }
      // query detail department info
      List<Department> departments = departmentService.batchQueryDepartments(departMap.keySet().toArray(new Long[]{}));
      // set department map
      departments.forEach(department -> departMap.putIfAbsent(department.getDepartId(), department));
      // set employee department
      employeeList.forEach(employee -> employee.setDepartment(departMap.get(employee.getDepartment().getDepartId())));
    } else {
      data.setTotalItems(0);
      data.setTotalPages(0);

    }
    return data;
  }

}
